package com;


import java.io.*;
import java.nio.ByteBuffer;
import java.util.*;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

/**
 * @ServerEndpoint 注解是一个类层次的注解，它的功能主要是将目前的类定义成一个websocket服务器端,
 *                 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 */
@ServerEndpoint(value = "/{devid}")//{}中的数据代表一个参数，多个参数用/分隔
public class WebSocketTest {
    // 用来存放每个客户端对应的MyWebSocket对象.若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
    public static final HashMap<String, WebSocketTest> dev_webSocket = new HashMap<>();
    // 与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    /**
     * 连接建立成功调用的方法
     *
     * @param session 可选的参数。session为与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(@PathParam(value = "devid") String devid, Session session) {
        this.session = session;
        dev_webSocket.put(devid, this); // 加入map中
        System.out.println("有连接接入" + devid);
        sendMessage(new File("50.h264")); //测试文件播放
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam(value = "devid") String devid) {
        dev_webSocket.remove(devid); // 从map中删除
        System.out.println(devid + "连接关闭");
        try {
            session.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误" + error.getMessage());
    }

    /**
     * 这个方法与上面几个方法不一样。没有用注解，是根据自己需要添加的方法。
     */
    public void sendMessage(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(byte[] video) {
        System.out.println("本帧数据长度为"+video.length);
        try {
            ByteBuffer bf = ByteBuffer.wrap(video);
            this.session.getBasicRemote().sendBinary(bf);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
//    public void sendMessage(File video) {
//        FileInputStream fi=null;
//        try {
//            fi=new FileInputStream(video);
//            FileChannel channel = fi.getChannel();
//            ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
//            while (channel.read(byteBuffer)!=-1){
//                byteBuffer.flip();
//                this.session.getBasicRemote().sendBinary(byteBuffer);
//                byteBuffer.clear();
//                try {
//                    Thread.sleep(30);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        }finally {
//            if (fi!=null){
//                try {
//                    fi.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }

    /**
     * sps / pps / 帧
     * @param file
     */
    public void sendMessage(File file) {
        FileInputStream fileInputStream=null;
        try {
            fileInputStream= new FileInputStream(file);
            int len=fileInputStream.available();
            byte[] tmp=new byte[len];
            byte[] frame;
            ByteBuffer byteBuffer;
            //找到帧
            int front=0;
            int read = fileInputStream.read(tmp);
            System.out.println("读完为-1"+read);
            for (int i=0;i< len;i++){
                if (i+3>len){
                    return;
                }
                if (tmp[i]==0&&tmp[i+1]==0&&tmp[i+2]==0&&tmp[i+3]==1){//非一次开头
                    if (i-4<0){
                        continue;
                    }
                    frame=new byte[i-front];
                    System.arraycopy(tmp,front,frame,0,frame.length);
                    byteBuffer=ByteBuffer.wrap(frame);
                    this.session.getBasicRemote().sendBinary(byteBuffer);
//                    System.out.println("发送数据帧长度"+Arrays.toString(frame));
                    front=i;
                    try {
                        Thread.sleep(500);
                        System.out.println("发送一次");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (IOException e) {
            System.out.println("用户退出网页");
        } finally {
            if (fileInputStream!=null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

//    public void sendMessage(File file) {
//        int count=0;
//        FileInputStream fileInputStream=null;
//        try {
//            fileInputStream= new FileInputStream(file);
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            int len=fileInputStream.available();
//            byte[] tmp=new byte[len];
//            byte[] frame;
//            ByteBuffer byteBuffer;
//            //找到帧
//            int front=0;
//            int read = fileInputStream.read(tmp);
//            System.out.println("读完为-1:"+read);
//            for (int i=0;i< len;i++){
//                if (i+4>len){
//                    frame=new byte[len-front];
//                    System.arraycopy(tmp,front,frame,0,frame.length);
//                    byteBuffer=ByteBuffer.wrap(frame);
//                    this.session.getBasicRemote().sendBinary(byteBuffer);
//    //                System.out.println("发送数据帧长度"+frame.length);
//                    System.out.println("发送数据帧长度"+Arrays.toString(frame));
//                    return;
//                }
//                if (tmp[i]==0&&tmp[i+1]==0&&tmp[i+2]==0&&tmp[i+3]==1&&tmp[i+4]==103){//非一次开头
//                    if (i-4<0){
//                        continue;
//                    }
//                    frame=new byte[i-front];
//                    System.arraycopy(tmp,front,frame,0,frame.length);
//                    byteBuffer=ByteBuffer.wrap(frame);
//                    this.session.getBasicRemote().sendBinary(byteBuffer);
//                    System.out.println("发送数据帧长度"+Arrays.toString(frame));
//                    try {
//                        Thread.sleep(30);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    front=i;
//                }
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            if (fileInputStream!=null){
//                try {
//                    fileInputStream.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }
}